home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.4 Applications 1997 August / SGI IRIX 6.4 Applications 1997 August.iso / dist / custlink.idb / usr / custlink / util / mailer.pl.z / mailer.pl
Encoding:
Perl Script  |  1997-07-30  |  6.5 KB  |  308 lines

  1. #!/usr/sbin/perl
  2. #
  3. # This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.
  4. #
  5. # A simple mailer that supports webjumper attachment and non-ascii content.
  6. # It is intended to be used within custreg and memphis.
  7. # command line:
  8. #
  9. # mailer.pl [-subject subject] 
  10. #           [-from from-string] [-cc cc-addr]
  11. #           [-attach type:filepath] dest < content
  12. #
  13.  
  14. #
  15. # constants
  16. #
  17. $flagExclusiveLock = 2;
  18. $flagUnlock = 8;
  19.  
  20. #
  21. # customizable variables
  22. #
  23. $mailerFile  = "/usr/tmp/custreg_mailer_$$.txt";
  24.  
  25. #
  26. # a list of charsets, the default will be iso-8859-1
  27. #
  28. %CHARSETS = (
  29.          'ja_JP',     'iso-2022-jp',
  30.          'ja_JP.EUC', 'iso-2022-jp',
  31.          'ko_KR',     'iso-2022-kr',
  32.          'ko_KR.EUC', 'iso-2022-kr',
  33.          'en_US',     'us-ascii',
  34.          'C',         'us-ascii',
  35.          'de',        'iso-8859-1',
  36.          'fr',        'iso-8859-1',
  37.          'fr_CA',     'iso-8859-1',
  38.          'es',        'iso-8859-1',
  39.          'es_MX',     'iso-8859-1',
  40.          );
  41.  
  42. #
  43. # lang, if it's a multi-byte language
  44. #
  45. %MULTIBYTELANG = (
  46.         'ja_JP',     1,
  47.         'ja_JP.EUC', 1,
  48.         'ko_KR',     1,
  49.         'ko_KR.EUC', 1,
  50.         );
  51. #
  52. # $INPUTS associative array stores input arguments
  53. %INPUTS = ();
  54.  
  55. #
  56. # start of mailer
  57. #
  58.  
  59. if ($#ARGV < 0) {
  60.     print <<End_Usage;
  61. Usage:
  62. mailer.pl flags dest < content
  63.  
  64. where flags can be:
  65.       [-subject subject]
  66.       [-from from-string] 
  67.       [-cc cc-addr]
  68.       [-attach type:filepath]
  69. End_Usage
  70.  
  71.     exit(1);
  72. }
  73. else {
  74.     #
  75.     # obtain cmd line arguments 
  76.     #
  77.     &getCmdLineArgs(*INPUTS);
  78.     
  79.     &buildMailFile(*INPUTS);
  80.     &sendMailFile();
  81. }
  82.  
  83.  
  84. #
  85. # obtain cmd line arguments
  86. #
  87. sub getCmdLineArgs
  88. {
  89.     #
  90.     # loop thru the cmdline options
  91.     #
  92.     $i = 0;
  93.     while($i <= $#ARGV) {
  94.     if ($ARGV[$i] eq "-subject") {
  95.         $i++;
  96.         $INPUTS{'subject'} = $ARGV[$i];
  97.     }
  98.     elsif ($ARGV[$i] eq "-from") {
  99.         $i++;
  100.         $INPUTS{'from'} = $ARGV[$i];
  101.     }
  102.     elsif ($ARGV[$i] eq "-cc") {
  103.         $i++;
  104.         $INPUTS{'cc'} = $ARGV[$i];
  105.     }
  106.     elsif ($ARGV[$i] eq "-attach") {
  107.         $i++;
  108.         $INPUTS{'attach'} = $ARGV[$i];
  109.     }
  110.     else {
  111.         #
  112.         # dest address.
  113.         #
  114.         $INPUTS{'dest'} = $ARGV[$i];
  115.     }
  116.     $i++;
  117.     }
  118. }
  119.  
  120. #
  121. # build the mailer file with proper MIME headers
  122. #
  123. sub buildMailFile
  124. {
  125.     open(FILE, "> $mailerFile") || die "Cannot open: $mailerfile: $!\n";
  126.     
  127.     flock(FILE, $flagExclusiveLock);
  128.  
  129.     #
  130.     # get host name
  131.     #
  132.     $host = `/usr/bsd/hostname`;
  133.     chop $host;
  134.     local(@a) = gethostbyname($host);
  135.     $host = $a[0] unless ! @a;
  136.  
  137.     #
  138.     # print the mail header
  139.     #
  140.     if ($INPUTS{'from'} ne "") {
  141.     if ($INPUTS{'from'} =~ /<\w+>/) {
  142.         print FILE "From: $INPUTS{'from'}\n";
  143.     }
  144.     else {
  145.         $login = getlogin || (getpwuid($<))[0] || "nobody";
  146.         if ($INPUTS{'to'} =~ /\@/) {
  147.         print FILE "From: $INPUTS{'from'} <$login@$host>\n";
  148.         }
  149.         else {
  150.         print FILE "From: $INPUTS{'from'} <$login>\n";
  151.         }
  152.     }
  153.     }
  154.  
  155.     print FILE "X-Mailer: mailer.pl (SGI/CustReg/mailer)\n";
  156.     print FILE "To: $INPUTS{'dest'}\n";
  157.     print FILE "Subject: $INPUTS{'subject'}\n";
  158.     print FILE "Cc: $cc\n";
  159.  
  160.     # 
  161.     # print the MIME header
  162.     #
  163.     print FILE "Mime-Version: 1.0\n";
  164.  
  165.     $boundary = "PART-BOUNDARY=.$$.$host";
  166.  
  167.     if ($INPUTS{'attach'}) {
  168.     print FILE "Content-Type: multipart/mixed;\n";
  169.     print FILE " boundary=\"$boundary\"\n\n";
  170.  
  171.     #
  172.     # separator
  173.     #
  174.     print FILE "--\n--$boundary\n";
  175.     }
  176.  
  177.     #
  178.     # email body
  179.     #
  180.     $lang = $ENV{'LANG'};
  181.     $charset = $CHARSETS{$lang};
  182.     if ($charset eq "") {
  183.     $charset = "us-ascii";
  184.     }
  185.     $content = "";
  186.     while(<STDIN>) { $content .= $_; }
  187.  
  188.     print FILE "Content-Type: text/plain; charset=$charset\n";
  189.  
  190.     #
  191.     # No encoding - Tony Tam 11/21/96
  192.     #
  193.     print FILE "\n";
  194.     print FILE $content;
  195.  
  196. ############################################################
  197. # TAKE OUT THIS SECTION BECAUSE MEMPHIS ALREADY DOES
  198. # ENCODING - Tony Tam 11/21/96
  199. #
  200. #    if (($lang eq "") || ($lang eq "en_US") || ($lang eq "C")) {
  201. #    print FILE "\n";
  202. #    print FILE $content;
  203. #    }
  204. #    elsif ($MULTIBYTELANG{$lang}) {
  205. #    print FILE "Content-Transter-Encoding: base64\n\n";
  206. #    print FILE &encodeBase64($content);
  207. #    }
  208. #    else {
  209. #    print FILE "Content-Transter-Encoding: quote-printable\n\n";
  210. #    print FILE &encodeQuotedPrint($content);
  211. #    }
  212. #######################################################
  213.  
  214.     print FILE "\n";
  215.  
  216.     #
  217.     # attachment. it's mostly webjumper so we use charset=us-ascii
  218.     #
  219.     if ($INPUTS{'attach'}) {
  220.     ($atype, $afilepath) = split(/:/, $INPUTS{'attach'});
  221.     open (AFILE, $afilepath) || die "Cannot open $afilepath: $!\n";
  222.  
  223.     print FILE "\n--$boundary\n";
  224.     print FILE "Content-Type: $atype; charset=us-ascii\n\n";
  225.     
  226.     while (<AFILE>) {
  227.         print FILE;
  228.     }
  229.  
  230.     #
  231.     # separator
  232.     #
  233.     print FILE "\n--$boundary--\n\n";
  234.     }
  235.     
  236.     flock(FILE, $flagUnlock);
  237.     close(FILE);
  238. }
  239.  
  240. sub sendMailFile
  241. {
  242.     open (MAIL, "| /usr/lib/sendmail -t -n") || die "Cannot do sendmail: $!\n";
  243.  
  244.     open (FILE, $mailerFile) || die "Cannot open $mailerFile: $!\n";
  245.  
  246.     while (<FILE>) {
  247.     print MAIL;
  248.     }
  249.     close (FILE);
  250.     close (MAIL);
  251.  
  252.     unlink $mailerFile;
  253. }
  254.  
  255. #
  256. # encodeBase64 is backward ported from perl5's Base64::encode
  257. # because perl5 is not bundled to 6.3, as of 7/28/96.
  258. #
  259. sub encodeBase64
  260. {
  261.     local ($res) = "";
  262.     local ($src) = shift;
  263.     local ($eol) = shift;
  264.     $eol = "\n" unless defined $eol;
  265.     $* = 1;                                      # enalble multi-line patterns
  266.     while ($src =~ /(.{1,45})/g) {
  267.     $res .= substr(pack('u', $1), 1);
  268.     chop($res);
  269.     }
  270.     $* = 0;                                      # disable multi-line patterns
  271.  
  272.     $res =~ tr|` -_|AA-Za-z0-9+/|;               # `# help emacs
  273.     # fix padding at the end
  274.     local ($padding) = (3 - length($_[0]) % 3) % 3;
  275.     $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
  276.     # break encoded string into lines of no more than 76 characters each
  277.     if (length $eol) {
  278.     $res =~ s/(.{1,76})/$1$eol/g;
  279.     }
  280.  
  281.     $res;
  282. }
  283.  
  284. #
  285. # encodeQuotedPrint is backward ported from perl5's QuotedPrint::encode
  286. # because perl5 is not bundled to 6.3, as of 7/28/96.
  287. #
  288. sub encodeQuotedPrint
  289. {
  290.     local ($res) = shift;
  291.     $res =~ s/([^ \t\n!-<>-~])/sprintf("=%02X", ord($1))/eg;  # rule #2,#3
  292.     $res =~ s/([ \t]+)$/
  293.     join('', map { sprintf("=%02X", ord($_)) } split('', $1)
  294.       )/eg;                        # rule #3 (encode whitespace at eol)
  295.  
  296.     # rule #5 (lines must be shorter than 76 chars, but we are not allowed
  297.     # to break =XX escapes.  This makes things complicated :-( )
  298.     local ($brokenlines) = "";
  299.     $brokenlines .= "$1=\n" while $res =~ s/^(.{74}([^=]{2})?)//;
  300.     # unnessesary to make a break at the last char
  301.     $brokenlines =~ s/=\n$// unless length $res;
  302.  
  303.     "$brokenlines$res";
  304. }
  305.  
  306.